

#ifndef W_SWITCH_LOCAL_AREA_VUE_H
#define W_SWITCH_LOCAL_AREA_VUE_H

#include <Arduino.h>
#include <ESP8266WebServer.h>
#include "LevelUri.h"
#include "LittleFS.h"

ESP8266WebServer vueWebServer(80);
/***
 * web文件20KB缓冲区
 * */
#define buff_size  (20 * 1024)
uint8_t buff[buff_size];


String getContentType(String filename) {
    if (vueWebServer.hasArg("download")) {
        return "application/octet-stream";
    } else if (filename.endsWith(".htm")) {
        return "text/html";
    } else if (filename.endsWith(".html")) {
        return "text/html";
    } else if (filename.endsWith(".css")) {
        return "text/css";
    } else if (filename.endsWith(".js")) {
        return "application/javascript";
    } else if (filename.endsWith(".png")) {
        return "image/png";
    } else if (filename.endsWith(".gif")) {
        return "image/gif";
    } else if (filename.endsWith(".jpg")) {
        return "image/jpeg";
    } else if (filename.endsWith(".ico")) {
        return "image/x-icon";
    } else if (filename.endsWith(".xml")) {
        return "text/xml";
    } else if (filename.endsWith(".pdf")) {
        return "application/x-pdf";
    } else if (filename.endsWith(".zip")) {
        return "application/x-zip";
    } else if (filename.endsWith(".gz")) {
        return "application/x-gzip";
    } else if (filename.endsWith(".svg")) {
        return "image/svg+xml";
    }
    return "text/plain";
}

/**
 * vue 基本的绑定函数
 * */
void handleRoot();
void handleAssets();
void handleNotFound();

inline void handleFile(const char *path) {
    File file = LittleFS.open(String(path) + ".gz", "r");
    if (!file) {
        Serial.println("There was an error opening the file for writing");
        handleNotFound();
        return;
    }
    size_t length = file.size();

    String header =
            "HTTP/1.1 200 OK\n"
            "Content-Type: {0}\n"
            "Content-Length: {1}\n"
            "Content-Encoding: gzip\n"
            "Connection: close\n\n";
    header.replace("{0}", getContentType(String(path)));
    header.replace("{1}", String(length));
    auto client = vueWebServer.client();
    client.write(header.c_str());
    client.flush();
    int count = length / buff_size;
    for (int i = 0; i < count; i++) {
        file.read(buff, buff_size);
        client.write(buff, buff_size);
        client.flush();
    }
    int lastLen = length % buff_size;
    if (lastLen) {
        file.read(buff, lastLen);
        client.write(buff, lastLen);
        client.flush();
    }
    file.close();
}

void handleRoot() {
    handleFile("/index.html");
}

/**
 * 静态资源一律走这里
 * */
void handleAssets() {
    const String &string = vueWebServer.uri();
    handleFile(string.c_str());
}

void handleNotFound() {
    String message = "File Not Found\n\n";
    message += "URI: ";
    message += vueWebServer.uri();
    message += "\nMethod: ";
    message += (vueWebServer.method() == HTTP_GET) ? "GET" : "POST";
    message += "\nArguments: ";
    message += vueWebServer.args();
    message += "\n";
    for (uint8_t i = 0; i < vueWebServer.args(); i++) {
        message += " " + vueWebServer.argName(i) + ": " + vueWebServer.arg(i) + "\n";
    }
    vueWebServer.send(404, "text/plain", message);
}


#endif //W_SWITCH_LOCAL_AREA_VUE_H
